home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <math.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include "ogl_shapes.h"
-
- #define TORUSWIRE 0
- #define TORUSSOLID 1
- #define CUBEWIRE 2
- #define CUBESOLID 3
- #define NUM_LISTS 4
-
- #define STACKDEPTH 10
- #define ADD_QUAD 1
- #define PI 3.1415926535897
-
- typedef struct {
- float mat[4][4];
- float norm[3][3];
- } mat_t;
-
- static mat_t matstack[STACKDEPTH] = {
- {{
- {1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}
- },
-
- {
- {1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {0.0, 0.0, 1.0}
- }
- }
- };
- static long identitymat = 1;
-
- static long mattop = 0;
-
- static GLuint lists[NUM_LISTS] = { 0, 0, 0, 0 };
-
- static GLvoid
- normalize(GLfloat v[3])
- {
- float d;
-
- d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
- if (d == 0.0) {
- fprintf(stderr, "normalize: zero length vector\n");
- v[0] = d = 1.0;
- }
- d = 1/d;
- v[0] *= d;
- v[1] *= d;
- v[2] *= d;
- }
-
- static void
- m_xformpt(GLfloat pin[3], GLfloat pout[3],
- GLfloat nin[3], GLfloat nout[3])
- {
- long i;
- float ptemp[3], ntemp[3];
- mat_t *m = &matstack[mattop];
-
- if (identitymat) {
- for (i = 0; i < 3; i++) {
- pout[i] = pin[i];
- nout[i] = nin[i];
- }
- return;
- }
- for (i = 0; i < 3; i++) {
- ptemp[i] = pin[0]*m->mat[0][i] +
- pin[1]*m->mat[1][i] +
- pin[2]*m->mat[2][i] +
- m->mat[3][i];
- ntemp[i] = nin[0]*m->norm[0][i] +
- nin[1]*m->norm[1][i] +
- nin[2]*m->norm[2][i];
- }
- for (i = 0; i < 3; i++) {
- pout[i] = ptemp[i];
- nout[i] = ntemp[i];
- }
- normalize(nout);
- }
-
- static GLvoid
- doughnut(GLfloat r, GLfloat R, long nsides, long rings,
- GLvoid (*savefunc)())
- {
- long i, j;
- float theta, phi, theta1, phi1;
- float p0[03], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
- float t0[2], t1[2], t2[2], t3[2];
-
- for (i = 0; i < rings; i++) {
- theta = (float)i*2.0*PI/rings;
- theta1 = (float)(i+1)*2.0*PI/rings;
- for (j = 0; j < nsides; j++) {
- phi = (float)j*2.0*PI/nsides;
- phi1 = (float)(j+1)*2.0*PI/nsides;
-
- t0[0] = ((float)i)/((float)rings);
- t0[1] = ((float)j)/((float)nsides);
-
- t1[0] = ((float)i+1)/((float)rings);
- t1[1] = ((float)j)/((float)nsides);
-
- t2[0] = ((float)i+1)/((float)rings);
- t2[1] = ((float)j+1)/((float)nsides);
-
- t3[0] = ((float)i)/((float)rings);
- t3[1] = ((float)j+1)/((float)nsides);
-
- p0[0] = cos(theta)*(R + r*cos(phi));
- p0[1] = -sin(theta)*(R + r*cos(phi));
- p0[2] = r*sin(phi);
-
- p1[0] = cos(theta1)*(R + r*cos(phi));
- p1[1] = -sin(theta1)*(R + r*cos(phi));
- p1[2] = r*sin(phi);
-
- p2[0] = cos(theta1)*(R + r*cos(phi1));
- p2[1] = -sin(theta1)*(R + r*cos(phi1));
- p2[2] = r*sin(phi1);
-
- p3[0] = cos(theta)*(R + r*cos(phi1));
- p3[1] = -sin(theta)*(R + r*cos(phi1));
- p3[2] = r*sin(phi1);
-
- n0[0] = cos(theta)*(cos(phi));
- n0[1] = -sin(theta)*(cos(phi));
- n0[2] = sin(phi);
-
- n1[0] = cos(theta1)*(cos(phi));
- n1[1] = -sin(theta1)*(cos(phi));
- n1[2] = sin(phi);
-
- n2[0] = cos(theta1)*(cos(phi1));
- n2[1] = -sin(theta1)*(cos(phi1));
- n2[2] = sin(phi1);
-
- n3[0] = cos(theta)*(cos(phi1));
- n3[1] = -sin(theta)*(cos(phi1));
- n3[2] = sin(phi1);
-
- m_xformpt(p0, p0, n0, n0);
- m_xformpt(p1, p1, n1, n1);
- m_xformpt(p2, p2, n2, n2);
- m_xformpt(p3, p3, n3, n3);
-
- (*savefunc)(ADD_QUAD, n3, t3, p3, n2, t2, p2, n1, t1, p1, n0, t0, p0);
- }
- }
- }
-
- static void
- drawbox(float x0, float x1, float y0, float y1,
- float z0, float z1, void (*savefunc)())
- {
- long i;
- float temp;
- float p0[3], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
- float t0[2], t1[2], t2[2], t3[2];
- float cv[8][3];
- float cnorms[6][3] = {
- {-1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {1.0, 0.0, 0.0},
- {0.0, -1.0, 0.0},
- {0.0, 0.0, 1.0},
- {0.0, 0.0, -1.0}
- };
- long faces[6][4] = {
- { 0, 1, 2, 3 },
- { 3, 2, 6, 7 },
- { 7, 6, 5, 4 },
- { 4, 5, 1, 0 },
- { 5, 6, 2, 1 },
- { 7, 4, 0, 3 }
- };
-
-
-
- if (x0 > x1) {
- temp = x0;
- x0 = x1;
- x1 = temp;
- }
- if (y0 > y1) {
- temp = y0;
- y0 = y1;
- y1 = temp;
- }
- if (z0 > z1) {
- temp = z0;
- z0 = z1;
- z1 = temp;
- }
- cv[0][0] = cv[1][0] = cv[2][0] = cv[3][0] = x0;
- cv[4][0] = cv[5][0] = cv[6][0] = cv[7][0] = x1;
- cv[0][1] = cv[1][1] = cv[4][1] = cv[5][1] = y0;
- cv[2][1] = cv[3][1] = cv[6][1] = cv[7][1] = y1;
- cv[0][2] = cv[3][2] = cv[4][2] = cv[7][2] = z0;
- cv[1][2] = cv[2][2] = cv[5][2] = cv[6][2] = z1;
- t0[0] = 0.0;
- t0[1] = 0.0;
- t1[0] = 0.0;
- t1[1] = 1.0;
- t2[0] = 1.0;
- t2[1] = 1.0;
- t3[0] = 1.0;
- t3[1] = 0.0;
- for (i = 0; i < 6; i++) {
- m_xformpt(&cv[faces[i][0]][0], p0, &cnorms[i][0], n0);
- m_xformpt(&cv[faces[i][1]][0], p1, &cnorms[i][0], n1);
- m_xformpt(&cv[faces[i][2]][0], p2, &cnorms[i][0], n2);
- m_xformpt(&cv[faces[i][3]][0], p3, &cnorms[i][0], n3);
- (*savefunc)(ADD_QUAD, n0, t0, p0, n1, t1, p1, n2, t2, p2, n3, t3, p3);
- }
- }
-
- static GLvoid
- savequad(long type,
- GLfloat * n0, GLfloat * t0, GLfloat * v0,
- GLfloat * n1, GLfloat * t1, GLfloat * v1,
- GLfloat * n2, GLfloat * t2, GLfloat * v2,
- GLfloat * n3, GLfloat * t3, GLfloat * v3)
- {
- glBegin (GL_POLYGON);
- glNormal3fv(n0);
- glVertex3fv(v0);
- glNormal3fv(n1);
- glVertex3fv(v1);
- glNormal3fv(n2);
- glVertex3fv(v2);
- glNormal3fv(n3);
- glVertex3fv(v3);
- glEnd();
- }
-
- static GLvoid
- savewirequad(long type,
- GLfloat * n0, GLfloat * t0, GLfloat * v0,
- GLfloat * n1, GLfloat * t1, GLfloat * v1,
- GLfloat * n2, GLfloat * t2, GLfloat * v2,
- GLfloat * n3, GLfloat * t3, GLfloat * v3)
- {
- glBegin (GL_LINE_LOOP);
- glNormal3fv(n0);
- glVertex3fv(v0);
- glNormal3fv(n1);
- glVertex3fv(v1);
- glNormal3fv(n2);
- glVertex3fv(v2);
- glNormal3fv(n3);
- glVertex3fv(v3);
- glEnd();
- }
-
- /* Create display lists for rendering torii. */
-
- static GLvoid
- wireTorus (GLvoid)
- {
- lists[TORUSWIRE] = glGenLists (1);
- glNewList(lists[TORUSWIRE], GL_COMPILE);
- doughnut(0.25, 0.75, 5, 10, savewirequad);
- glEndList();
- }
-
- static GLvoid
- solidTorus (GLvoid)
- {
- lists[TORUSSOLID] = glGenLists (1);
- glNewList(lists[TORUSSOLID], GL_COMPILE);
- doughnut(0.25, 0.75, 8, 15, savequad);
- glEndList();
- }
- static GLvoid
- wireCube (GLvoid)
- {
- lists[CUBEWIRE] = glGenLists (1);
- glNewList(lists[CUBEWIRE], GL_COMPILE);
- drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savewirequad);
- glEndList();
- }
-
- static GLvoid
- solidCube (GLvoid)
- {
- lists[CUBESOLID] = glGenLists (1);
- glNewList(lists[CUBESOLID], GL_COMPILE);
- drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savequad);
- glEndList();
- }
-
- /* Render the appropriate display lists for the torii. */
-
- GLvoid
- doWireTorus (void)
- {
- if (glIsList(lists[TORUSWIRE]) == 0)
- wireTorus ();
- glCallList(lists[TORUSWIRE]);
- }
-
- GLvoid
- doSolidTorus (void)
- {
- if (glIsList(lists[TORUSSOLID]) == 0)
- solidTorus ();
- glCallList(lists[TORUSSOLID]);
- }
-
- GLvoid
- doWireCube (void)
- {
- if (glIsList(lists[CUBEWIRE]) == 0)
- wireCube ();
- glCallList(lists[CUBEWIRE]);
- }
-
- GLvoid
- doSolidCube (void)
- {
- if (glIsList(lists[CUBESOLID]) == 0)
- solidCube ();
- glCallList(lists[CUBESOLID]);
- }
-
- GLvoid
- initStockShapes (GLvoid)
- {
- wireTorus();
- solidTorus();
- wireCube();
- solidCube();
- }
-
-